const
  GeneralCategory = Object.freeze([
    // https://www.unicode.org/Public/UCD/latest/ucd/PropertyValueAliases.txt
    'C',  'Other',                //  # Cc | Cf | Cn | Co | Cs
    'Cc', 'Control',
    'Cf', 'Format',
    'Cn', 'Unassigned',
    'Co', 'Private_Use',
    'Cs', 'Surrogate',
    'L',  'Letter',               //  # Ll | Lm | Lo | Lt | Lu
    'LC', 'Cased_Letter',         //  # Ll | Lt | Lu
    'Ll', 'Lowercase_Letter',
    'Lm', 'Modifier_Letter',
    'Lo', 'Other_Letter',
    'Lt', 'Titlecase_Letter',
    'Lu', 'Uppercase_Letter',
    'M',  'Mark',                 //  # Mc | Me | Mn
    'Mc', 'Spacing_Mark',
    'Me', 'Enclosing_Mark',
    'Mn', 'Nonspacing_Mark',
    'N',  'Number',               //  # Nd | Nl | No
    'Nd', 'Decimal_Number',
    'Nl', 'Letter_Number',
    'No', 'Other_Number',
    'P',  'Punctuation',          //  # Pc | Pd | Pe | Pf | Pi | Po | Ps
    'Pc', 'Connector_Punctuation',
    'Pd', 'Dash_Punctuation',
    'Pe', 'Close_Punctuation',
    'Pf', 'Final_Punctuation',
    'Pi', 'Initial_Punctuation',
    'Po', 'Other_Punctuation',
    'Ps', 'Open_Punctuation',
    'S',  'Symbol',               //  # Sc | Sk | Sm | So
    'Sc', 'Currency_Symbol',
    'Sk', 'Modifier_Symbol',
    'Sm', 'Math_Symbol',
    'So', 'Other_Symbol',
    'Z',  'Separator',            //  # Zl | Zp | Zs
    'Zl', 'Line_Separator',
    'Zp', 'Paragraph_Separator',
    'Zs', 'Space_Separator',
  ]),
  Scripts = Object.freeze([
    // https://www.unicode.org/Public/UCD/latest/ucd/PropertyValueAliases.txt
    'Adlm', 'Adlam',
    'Aghb', 'Caucasian_Albanian',
    'Ahom', 'Ahom',
    'Arab', 'Arabic',
    'Armi', 'Imperial_Aramaic',
    'Armn', 'Armenian',
    'Avst', 'Avestan',
    'Bali', 'Balinese',
    'Bamu', 'Bamum',
    'Bass', 'Bassa_Vah',
    'Batk', 'Batak',
    'Beng', 'Bengali',
    'Bhks', 'Bhaiksuki',
    'Bopo', 'Bopomofo',
    'Brah', 'Brahmi',
    'Brai', 'Braille',
    'Bugi', 'Buginese',
    'Buhd', 'Buhid',
    'Cakm', 'Chakma',
    'Cans', 'Canadian_Aboriginal',
    'Cari', 'Carian',
    'Cham', 'Cham',
    'Cher', 'Cherokee',
    'Copt', 'Coptic',             // ; Qaac
    'Cprt', 'Cypriot',
    'Cyrl', 'Cyrillic',
    'Deva', 'Devanagari',
    'Dogr', 'Dogra',
    'Dsrt', 'Deseret',
    'Dupl', 'Duployan',
    'Egyp', 'Egyptian_Hieroglyphs',
    'Elba', 'Elbasan',
    'Ethi', 'Ethiopic',
    'Geor', 'Georgian',
    'Glag', 'Glagolitic',
    'Gong', 'Gunjala_Gondi',
    'Gonm', 'Masaram_Gondi',
    'Goth', 'Gothic',
    'Gran', 'Grantha',
    'Grek', 'Greek',
    'Gujr', 'Gujarati',
    'Guru', 'Gurmukhi',
    'Hang', 'Hangul',
    'Hani', 'Han',
    'Hano', 'Hanunoo',
    'Hatr', 'Hatran',
    'Hebr', 'Hebrew',
    'Hira', 'Hiragana',
    'Hluw', 'Anatolian_Hieroglyphs',
    'Hmng', 'Pahawh_Hmong',
    'Hrkt', 'Katakana_Or_Hiragana',
    'Hung', 'Old_Hungarian',
    'Ital', 'Old_Italic',
    'Java', 'Javanese',
    'Kali', 'Kayah_Li',
    'Kana', 'Katakana',
    'Khar', 'Kharoshthi',
    'Khmr', 'Khmer',
    'Khoj', 'Khojki',
    'Knda', 'Kannada',
    'Kthi', 'Kaithi',
    'Lana', 'Tai_Tham',
    'Laoo', 'Lao',
    'Latn', 'Latin',
    'Lepc', 'Lepcha',
    'Limb', 'Limbu',
    'Lina', 'Linear_A',
    'Linb', 'Linear_B',
    'Lisu', 'Lisu',
    'Lyci', 'Lycian',
    'Lydi', 'Lydian',
    'Mahj', 'Mahajani',
    'Maka', 'Makasar',
    'Mand', 'Mandaic',
    'Mani', 'Manichaean',
    'Marc', 'Marchen',
    'Medf', 'Medefaidrin',
    'Mend', 'Mende_Kikakui',
    'Merc', 'Meroitic_Cursive',
    'Mero', 'Meroitic_Hieroglyphs',
    'Mlym', 'Malayalam',
    'Modi', 'Modi',
    'Mong', 'Mongolian',
    'Mroo', 'Mro',
    'Mtei', 'Meetei_Mayek',
    'Mult', 'Multani',
    'Mymr', 'Myanmar',
    'Narb', 'Old_North_Arabian',
    'Nbat', 'Nabataean',
    'Newa', 'Newa',
    'Nkoo', 'Nko',
    'Nshu', 'Nushu',
    'Ogam', 'Ogham',
    'Olck', 'Ol_Chiki',
    'Orkh', 'Old_Turkic',
    'Orya', 'Oriya',
    'Osge', 'Osage',
    'Osma', 'Osmanya',
    'Palm', 'Palmyrene',
    'Pauc', 'Pau_Cin_Hau',
    'Perm', 'Old_Permic',
    'Phag', 'Phags_Pa',
    'Phli', 'Inscriptional_Pahlavi',
    'Phlp', 'Psalter_Pahlavi',
    'Phnx', 'Phoenician',
    'Plrd', 'Miao',
    'Prti', 'Inscriptional_Parthian',
    'Rjng', 'Rejang',
    'Rohg', 'Hanifi_Rohingya',
    'Runr', 'Runic',
    'Samr', 'Samaritan',
    'Sarb', 'Old_South_Arabian',
    'Saur', 'Saurashtra',
    'Sgnw', 'SignWriting',
    'Shaw', 'Shavian',
    'Shrd', 'Sharada',
    'Sidd', 'Siddham',
    'Sind', 'Khudawadi',
    'Sinh', 'Sinhala',
    'Sogd', 'Sogdian',
    'Sogo', 'Old_Sogdian',
    'Sora', 'Sora_Sompeng',
    'Soyo', 'Soyombo',
    'Sund', 'Sundanese',
    'Sylo', 'Syloti_Nagri',
    'Syrc', 'Syriac',
    'Tagb', 'Tagbanwa',
    'Takr', 'Takri',
    'Tale', 'Tai_Le',
    'Talu', 'New_Tai_Lue',
    'Taml', 'Tamil',
    'Tang', 'Tangut',
    'Tavt', 'Tai_Viet',
    'Telu', 'Telugu',
    'Tfng', 'Tifinagh',
    'Tglg', 'Tagalog',
    'Thaa', 'Thaana',
    'Thai', 'Thai',
    'Tibt', 'Tibetan',
    'Tirh', 'Tirhuta',
    'Ugar', 'Ugaritic',
    'Vaii', 'Vai',
    'Wara', 'Warang_Citi',
    'Xpeo', 'Old_Persian',
    'Xsux', 'Cuneiform',
    'Yiii', 'Yi',
    'Zanb', 'Zanabazar_Square',
    'Zinh', 'Inherited',         // ; Qaai
    'Zyyy', 'Common',
    'Zzzz', 'Unknown',
  ]),
  BinaryProperties = Object.freeze([
    // https://www.unicode.org/Public/UCD/latest/ucd/PropertyAliases.txt
    // 'Hyphen', (Stabilized as of 4.0.0; Deprecated as of 6.0.0)

    'AHex',     'ASCII_Hex_Digit',
    'Alpha',    'Alphabetic',
    'Bidi_C',   'Bidi_Control',
    'Bidi_M',   'Bidi_Mirrored',
    'Cased',    'Cased',
    'CE',       'Composition_Exclusion',
    'CI',       'Case_Ignorable',
    'Comp_Ex',  'Full_Composition_Exclusion',
    'CWCF',     'Changes_When_Casefolded',
    'CWCM',     'Changes_When_Casemapped',
    'CWKCF',    'Changes_When_NFKC_Casefolded',
    'CWL',      'Changes_When_Lowercased',
    'CWT',      'Changes_When_Titlecased',
    'CWU',      'Changes_When_Uppercased',
    'Dash',     'Dash',
    'Dep',      'Deprecated',
    'DI',       'Default_Ignorable_Code_Point',
    'Dia',      'Diacritic',
    'Ext',      'Extender',
    'Gr_Base',  'Grapheme_Base',
    'Gr_Ext',   'Grapheme_Extend',
    'Gr_Link',  'Grapheme_Link',
    'Hex',      'Hex_Digit',
    'Hyphen',   'Hyphen',
    'IDC',      'ID_Continue',
    'Ideo',     'Ideographic',
    'IDS',      'ID_Start',
    'IDSB',     'IDS_Binary_Operator',
    'IDST',     'IDS_Trinary_Operator',
    'Join_C',   'Join_Control',
    'LOE',      'Logical_Order_Exception',
    'Lower',    'Lowercase',
    'Math',     'Math',
    'NChar',    'Noncharacter_Code_Point',
    'OAlpha',   'Other_Alphabetic',
    'ODI',      'Other_Default_Ignorable_Code_Point',
    'OGr_Ext',  'Other_Grapheme_Extend',
    'OIDC',     'Other_ID_Continue',
    'OIDS',     'Other_ID_Start',
    'OLower',   'Other_Lowercase',
    'OMath',    'Other_Math',
    'OUpper',   'Other_Uppercase',
    'Pat_Syn',  'Pattern_Syntax',
    'Pat_WS',   'Pattern_White_Space',
    'PCM',      'Prepended_Concatenation_Mark',
    'QMark',    'Quotation_Mark',
    'Radical',  'Radical',
    'RI',       'Regional_Indicator',
    'SD',       'Soft_Dotted',
    'STerm',    'Sentence_Terminal',
    'Term',     'Terminal_Punctuation',
    'UIdeo',    'Unified_Ideograph',
    'Upper',    'Uppercase',
    'VS',       'Variation_Selector',
    'WSpace',   'White_Space',                // ; space
    'XIDC',     'XID_Continue',
    'XIDS',     'XID_Start',
    'XO_NFC',   'Expands_On_NFC',
    'XO_NFD',   'Expands_On_NFD',
    'XO_NFKC',  'Expands_On_NFKC',
    'XO_NFKD',  'Expands_On_NFKD',
  ]),
  Control = Object.freeze([
    // keep sort
    // https://www.unicode.org/Public/UCD/latest/ucd/NameAliases.txt
    'ACK', 0x06,    // ACKNOWLEDGE
    'APC', 0x9F,    // APPLICATION PROGRAM COMMAND
    'BEL', 0x07,    // ALERT
    'BPH', 0x82,    // BREAK PERMITTED HERE
    'BS',  0x08,    // BACKSPACE
    'CAN', 0x18,    // CANCEL
    'CCH', 0x94,    // CANCEL CHARACTER
    'CR',  0x0D,    // CARRIAGE RETURN
    'CSI', 0x9B,    // CONTROL SEQUENCE INTRODUCER
    'DC1', 0x11,    // DEVICE CONTROL ONE
    'DC2', 0x12,    // DEVICE CONTROL TWO
    'DC3', 0x13,    // DEVICE CONTROL THREE
    'DC4', 0x14,    // DEVICE CONTROL FOUR
    'DCS', 0x90,    // DEVICE CONTROL STRING
    'DEL', 0x7F,    // DELETE
    'DLE', 0x10,    // DATA LINK ESCAPE
    'ENQ', 0x05,    // ENQUIRY
    'EOL', 0x0A,    // END OF LINE
    'EOM', 0x19,    // END OF MEDIUM
    'EOT', 0x04,    // END OF TRANSMISSION
    'EPA', 0x97,    // END OF PROTECTED AREA
    'ESA', 0x87,    // END OF SELECTED AREA
    'ESC', 0x1B,    // ESCAPE
    'ETB', 0x17,    // END OF TRANSMISSION BLOCK
    'ETX', 0x03,    // END OF TEXT
    'FF',  0x0C,    // FORM FEED
    'FS',  0x1C,    // FILE SEPARATOR
    'GS',  0x1D,    // GROUP SEPARATOR
    'HOP', 0x81,    // HIGH OCTET PRESET
    'HT',  0x09,    // HORIZONTAL
    'HTJ', 0x89,    // HORIZONTAL TABULATION WITH JUSTIFICATION
    'HTS', 0x88,    // HORIZONTAL TABULATION SET
    'IND', 0x84,    // INDEX
    'LF',  0x0A,    // LINE FEED
    'MW',  0x95,    // MESSAGE WAITING
    'NAK', 0x15,    // NEGATIVE ACKNOWLEDGE
    'NBH', 0x83,    // NO BREAK HERE
    'NEL', 0x85,    // NEXT LINE
    'NL',  0x0A,    // NEW LINE
    'NUL', 0x00,    // NULL
    'OSC', 0x9D,    // OPERATING SYSTEM COMMAND
    'PAD', 0x80,    // PADDING CHARACTER
    'PLD', 0x8B,    // PARTIAL LINE DOWN
    'PLU', 0x8C,    // PARTIAL LINE UP
    'PM',  0x9E,    // PRIVACY MESSAGE
    'PU1', 0x91,    // PRIVATE USE-1
    'PU2', 0x92,    // PRIVATE USE-2
    'RI',  0x8D,    // REVERSE INDEX
    'RS',  0x1E,    // RECORD SEPARATOR
    'SCI', 0x9A,    // SINGLE CHARACTER INTRODUCER
    'SGC', 0x99,    // SINGLE GRAPHIC CHARACTER INTRODUCER
    'SI',  0x0F,    // SHIFT IN
    'SO',  0x0E,    // SHIFT OUT
    'SOH', 0x01,    // START OF HEADING
    'SOS', 0x98,    // START OF STRING
    'SP',  0x20,    // SPACE
    'SPA', 0x96,    // START OF PROTECTED AREA
    'SS2', 0x8E,    // SINGLE-SHIFT-2
    'SS3', 0x8F,    // SINGLE-SHIFT-3
    'SSA', 0x86,    // START OF SELECTED AREA
    'ST',  0x9C,    // STRING TERMINATOR
    'STS', 0x93,    // SET TRANSMIT STATE
    'STX', 0x02,    // START OF TEXT
    'SUB', 0x1A,    // SUBSTITUTE
    'SYN', 0x16,    // SYNCHRONOUS IDLE
    'TAB', 0x09,    // HORIZONTAL
    'US',  0x1F,    // UNIT SEPARATOR
    'VT',  0x0B,    // VERTICAL TABULATION
    'VTS', 0x8A,    // VERTICAL TABULATION SET
  ]),
  POSIX = Object.freeze([
    // bracket ([:xxxxx:] | negative [:^xxxxx:])
    'alnum',  // alphanumeric     [0-9A-Za-z]
    'alpha',  // alphabetic       [A-Za-z]
    'ascii',  // ASCII            [\x00-\x7F]
    'blank',  // blank            [\t\x20])
    'cntrl',  // control          [\x00-\x1F\x7F]
    'digit',  // digits           [0-9]
    'graph',  // graphical        [!-~]
    'lower',  // lower case       [a-z]
    'print',  // printable        [\x20-~] == [ [:graph:]]
    'punct',  // punctuation      [!-/:-@[-`{-~]
    'space',  // whitespace       [\t\n\v\f\r\x20]
    'upper',  // upper case       [A-Z]
    'word',   // word characters  [0-9A-Za-z_]
    'xdigit', // hex digit        [0-9A-Fa-f])
  ])

const patterns = Object.freeze([
  'Alternation',
  'Anchor',
  'Any',
  'BinaryPropertie',
  'Codepoint',
  'GeneralCategory',
  'Group',
  'Matcher',
  'Native',
  'Negative',
  'POSIX',
  'Quantifier',
  'Range',
  'Reference',
  'Script',
  'Series',
  'Set',
])

function patternOf (sign) {
  return patterns[sign] || 'unreachable'
}

export {
  POSIX,
  BinaryProperties,
  Control,
  GeneralCategory,
  Scripts,
  patternOf
}
